#ifndef _DOWNWARD_COMMUNICATION_H
#define _DOWNWARD_COMMUNICATION_H

#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>

/**
 * 下行通讯类型
 */
typedef enum
{
    CommLevel0 = 0,
    CommLevel1,
    CommLevel2,
    CommLevel3,
    
}DOWN_COMM_TYPE;

typedef enum
{
    Task_IsOver,
    Task_IsWait,
    Task_IsOk,
}DOWN_TASK_STATE;

/**
 * 通讯任务开始调用的函数接口 返回DOWN_TASK_STATE代表通讯任务状态
 * 该方法是选配的，如果申请通信任务是单次的，那么不需要进行状态管理
 */
typedef DOWN_TASK_STATE F_TaskState(void *fun);

/**
 * 通讯任务发送调用的函数接口 返回数据发送的长度
 * fun为输入自定义参数，pBuf为输入指针
 */
typedef int32_t  F_TaskSend(void *fun, uint8_t *pBuf);

/**
 * 通讯任务接收调用的函数接口 返回值无定义
 */
typedef int32_t  F_TaskRecv(void *fun, uint8_t *pBuf, int32_t len);

/**
 * 一个下行通讯任务的属性
 */
typedef struct
{
    F_TaskState *pTaskState;
    F_TaskSend  *pTaskSend;
    F_TaskRecv  *pTaskRecv;
}DOWN_COMM_TASK;

/**
 * 检测同类型的任务是否正在执行或者等待执行
 */
static inline bool DownCommTaskIsBusy(DOWN_COMM_TASK *pDownTask)
{
    if(pDownTask->pTaskSend != NULL) return true;
    return false;
}

/**
 * 取消通信任务
 * 置通道状态函数为空，这样在本次通信结束后
 */
static inline bool DownCommTaskCancel(DOWN_COMM_TASK *pDownTask, bool isIdle)
{
    pDownTask->pTaskState = NULL;
    pDownTask->pTaskRecv = NULL;
    
    /* 如果任务不再执行，那么直接取消接收函数、状态函数、发送函数；
     * 如果任务正在执行，那么取消接收函数；再取消状态函数，通信结束后会自动清空发送函数 */
    if(isIdle) pDownTask->pTaskSend = NULL;
    
    return true;
}

/**
 * 申请通信任务
 */
static inline bool DownCommTaskApply(DOWN_COMM_TASK *pDownTask, F_TaskState *pSt, F_TaskSend *pTx, F_TaskRecv *pRx)
{
    if(pTx == NULL) return false;
    
    if(pDownTask->pTaskSend != NULL) return false;
    
    pDownTask->pTaskState = pSt;
    pDownTask->pTaskSend = pTx;
    pDownTask->pTaskRecv = pRx;
    return true;
}

#endif
